package cn.xiyun.xiyuncc.service.impl;

import cn.xiyun.xiyuncc.domain.Login;
import cn.xiyun.xiyuncc.domain.User;
import cn.xiyun.xiyuncc.domain.UserAccount;
import cn.xiyun.xiyuncc.domain.UserBaseInfo;
import cn.xiyun.xiyuncc.dto.RegisterDto;
import cn.xiyun.xiyuncc.exception.OperationException;
import cn.xiyun.xiyuncc.feignClient.LoginFeignClient;
import cn.xiyun.xiyuncc.mapper.UserAccountMapper;
import cn.xiyun.xiyuncc.mapper.UserBaseInfoMapper;
import cn.xiyun.xiyuncc.mapper.UserMapper;
import cn.xiyun.xiyuncc.result.JSONResult;
import cn.xiyun.xiyuncc.service.IUserService;
import cn.xiyun.xiyuncc.util.AssertUtil;
import cn.xiyun.xiyuncc.util.BitStatesUtils;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author xiyun.maple
 * @since 2023-03-08
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    /**
     * 客户端用户
     */
    private static final Integer login_type_web = 1;
    /**
     * 管理员用户
     */
    private static final Integer login_Administrator = 0;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserBaseInfoMapper userBaseInfoMapper;
    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private LoginFeignClient loginFeignClient;

    /**
     * 添加用户
     * @param registerDto
     */
    @Override
    // 分布式事务
    @GlobalTransactional(rollbackFor = Exception.class)
    public void register(RegisterDto registerDto) {
        String smsCode = registerDto.getSmsCode();
        String mobile = registerDto.getMobile();
        String password = registerDto.getPassword();
        // 获取redis中的验证码
        String st = (String) redisTemplate.opsForValue().get(mobile);
        AssertUtil.isNotNull(st, "短信验证码过期");
        AssertUtil.isEquals(smsCode, st, "短信验证码不正确");
        // 判断手机号是否注册
        EntityWrapper<User> userEntityWrapper = new EntityWrapper<>();
        Wrapper<User> phone = userEntityWrapper.eq("phone", mobile);
        User user1 = selectOne(phone);
        AssertUtil.isNull(user1, "此手机号已注册请使用短信验证码登录");
        // 获取login获取 id
        Long idLong = loginsSave(registerDto);
        //添加user获取id
        Long userID = userSave(registerDto, idLong);
        // 添加UserBaseInfo
        userBaseInfoSave(userID);
        // 添加UserAccount
        userAccountSave(userID);
    }
    /**
     * 添加到login
     * @param registerDto
     * @return
     */
    public Long loginsSave(RegisterDto registerDto) {
        // 添加login
        Login login = new Login();
        login.setUsername(registerDto.getMobile());
        login.setPassword(registerDto.getPassword());
        login.setType(login_type_web);
        JSONResult jsonResult = loginFeignClient.saveOrUpdate(login);
        AssertUtil.isTrue(jsonResult.isSuccess(), "服务异常请稍后重试");
        String idStr = jsonResult.getData().toString();
        long idLong = Long.parseLong(idStr);
        return idLong;
    }
    /**
     * 添加到user
     * @param registerDto
     * @return
     */
    public Long userSave(RegisterDto registerDto, Long idLong) {
        // 添加user
        User user = new User();
        user.setPhone(registerDto.getMobile());
        user.setLoginId(idLong);
        user.setNickName("xiyuncc" + registerDto.getMobile());
        user.setCreateTime(new Date().getTime());
        long l = BitStatesUtils.addState(BitStatesUtils.OP_REGISTED, BitStatesUtils.OP_ACTIVED);
        long state = BitStatesUtils.addState(l, BitStatesUtils.OP_AUTHED_PHONE);
        user.setBitState(state);
        userMapper.insert(user);
        return user.getId();
    }
    /**
     * 添加到userBaseInfo
     * @param userID
     * @return
     */
    public void userBaseInfoSave(Long userID) {
        // 添加userBaseInfo
        UserBaseInfo userBaseInfo = new UserBaseInfo();
        userBaseInfo.setId(userID);
        userBaseInfo.setCreateTime(new Date().getTime());
        userBaseInfo.setRegChannel(1);
        userBaseInfo.setReferId(userID);
        userBaseInfoMapper.insert(userBaseInfo);
    }
    /**
     * 添加到userAccount
     * @param userID
     * @return
     */
    public void userAccountSave(Long userID) {
        // 添加UserAccount
        UserAccount userAccount = new UserAccount();
        userAccount.setId(userID);
        userAccount.setCreateTime(new Date().getTime());
        userAccount.setFrozenAmount(new BigDecimal(0));
        userAccount.setUsableAmount(new BigDecimal(0));
        userAccountMapper.insert(userAccount);
    }

    /**
     * 根据电话号码查询用户信息
     * @param phone
     * @return
     */
    @Override
    public User phoneToUser(String phone) {
        EntityWrapper<User> userEntityWrapper = new EntityWrapper<>();
        Wrapper<User> phoneQuery = userEntityWrapper.eq("phone", phone);
        User user1 = selectOne(phoneQuery);
        return user1;
    }
}
